import {IResourceManager} from "./IResourceManager";
import Asset = cc.Asset;
import GameFrameworkModule from "../Base/GameFrameworkModule";
import ccclass = cc._decorator.ccclass;
@ccclass("ResourceManager")
export default class ResourceManager implements IResourceManager, GameFrameworkModule {
    loadUIAsset(paths: string, onComplete: (error: Error, assets: cc.Prefab|Array<cc.Prefab>) => void, onProgress?: (finish: number, total: number, item: cc.AssetManager.RequestItem) => void) {
        cc.resources.load(paths,((error, assets) => {
            if (error) {
                cc.error(error);
                return;
            }
            let tempassets:cc.Prefab|Array<cc.Prefab> =  assets as cc.Prefab|Array<cc.Prefab>;
            onComplete(error,tempassets);
        }))
    }
    private readonly assetBundleCache:Map<string,cc.AssetManager.Bundle> = new Map<string, cc.AssetManager.Bundle>();
    load<T extends cc.Asset>(paths: string | string[], type: typeof cc.Asset, onComplete: (error: Error, assets: (Array<T> | T)) => void, onProgress?: (finish: number, total: number, item: cc.AssetManager.RequestItem) => void): void {
        cc.resources.load(paths, type, onProgress, (err, asset) => {
            if (err) {
                cc.error(err);
                return;
            }
            if (asset instanceof Asset) {
                let cachePath: string = undefined;
                if (cc.assetManager.cacheManager) {
                    cachePath = cc.assetManager.cacheManager.getCache(asset.nativeUrl);
                }
                if (cachePath){
                    cc.resources.load(cachePath, type, onProgress, onComplete);
                    return;
                }
            } else {
                for (let i = 0; i < asset.length; i++) {
                    let cachePath: string = undefined;
                    if (cc.assetManager.cacheManager) {
                        cachePath = cc.assetManager.cacheManager.getCache(asset[i].nativeUrl);
                    }
                    if (cachePath){
                        cc.resources.load(cachePath, type, onProgress, onComplete);
                        return;
                    }
                }
            }
            onComplete(err,asset as (Array<T> | T));
        });
    }

    loadTextAsset(paths: string | string[], onComplete: (error: Error, assets: (Array<cc.TextAsset> | cc.TextAsset)) => void, onProgress?: (finish: number, total: number, item: cc.AssetManager.RequestItem) => void): void {
        this.load(paths, cc.TextAsset, onComplete, onProgress);
    }

    get Priority(): number {
        return 960;
    }

    Shutdown(): void {
        cc.assetManager.releaseAll();
        this.assetBundleCache.clear();
    }

    Update(elapseSeconds: number, realElapseSeconds: number): void {
    }

    get baseName(): string {
        return "GameFrameworkModule";
    }

    loadJsonAsset(paths: string | string[], onComplete: (error: Error, assets: (cc.JsonAsset | Array<cc.JsonAsset>)) => void, onProgress?: (finish: number, total: number, item: cc.AssetManager.RequestItem) => void): void {
        this.load(paths, cc.JsonAsset, onComplete, onProgress);
    }

    getBundle(name: string):cc.AssetManager.Bundle {
        if(this.assetBundleCache.has(name)){
            return this.assetBundleCache.get(name);
        }
        let bundle = cc.assetManager.getBundle(name)
        this.assetBundleCache.set(name,bundle);
        return bundle;
    }

    loadSoundAsset(paths: string | string[], type: cc.AudioClip, onComplete: (error: Error, assets: (cc.AudioClip | Array<cc.AudioClip>)) => void, onProgress?: (finish: number, total: number, item: cc.AssetManager.RequestItem) => void) {
    }

    UnloadAsset(asset: string, type: typeof cc.Asset) {
        cc.resources.release(asset,type);
    }



}